package com.bankcomm.voice;

import java.util.Stack;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bankcomm.BankcommApplication;
import com.bankcomm.R;
import com.bankcomm.common.ConfigManager;
import com.bankcomm.common.LPMid;
import com.bankcomm.ui.BOCMainHome;
import com.bankcomm.util.LPUtils;
import com.rytong.tools.clienthello.ClientHello;
import com.rytong.tools.httpconnect.WaitDialog;
import com.rytong.tools.utils.LPToastUtil;
import com.rytong.tools.utils.Utils;
import com.xioai.framework.api.jsonbean.Plugin;
import com.xioai.framework.api.jsonbean.Response;
import com.xioai.framework.voicecontrol.VcSession;
import com.xioai.framework.voicecontrol.VoiceBundle;
import com.xioai.framework.voicecontrol.VoiceControl;
import com.xioai.framework.voicecontrol.VoiceControlListener;
import com.xioai.framework.voicecontrol.player.PlayerCallBack;

/**
 * 语音框架
 * @author liujia (liujia9234@126.com)
 * @data @2012-2-17
 * @version 1.0
 * <ul>
 * 		<li>1.0 创建</li>
 * </ul>
 */
public class VoiceFrameActivity extends FragmentActivity implements OnClickListener {

	public static final String TAG = "VoiceFrameActivity"; 
	public static final String VOICE_ASK_AREA = "android.bcm";
	public static final String VOICE_SERVER_IP = "bankcomm.xiaoi.com";
	public static final int VOICE_SERVER_PORT = 8080;
	
	public Stack<Fragment> fragmentStack = new Stack<Fragment>();
	protected Stack<String> titleStack = new Stack<String>();
	
	public static final int TITLE_LENGTH = 6;
	private SoundManager soundManger;
	private ImageView logoImageViewLeft;
	private Button navigationButtonLeft;
	private TextView navigationTxtLeft;
	private TextView navigationTitleText;
	private LinearLayout specGroup;
	private Button frameworkExistBtn;
	
	protected VoiceControl  vc = null;
	private Handler handler = new Handler();
	private CallForward cf = new CallForward();
	private ImageButton microphoneBtn = null;
	private Button backServerBtn = null;
	private Button lifeServerBtn = null;
	private Drawable[] volumeImages = null;
	private ImageView mic;
	private long last_onclik_date = System.currentTimeMillis();
	private RelativeLayout navigationBar;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.xiaoi_voice_frame);
		mic=(ImageView) findViewById(R.id.voice_mic_img);
		soundManger = SoundManager.getInstance(VoiceFrameActivity.this);
		microphoneBtn = (ImageButton) findViewById(R.id.microphoneBtn);
		backServerBtn = (Button) findViewById(R.id.back_server);
		backServerBtn.setOnClickListener(this);
		lifeServerBtn = (Button) findViewById(R.id.life_server);
		lifeServerBtn.setOnClickListener(this);
		navigationBar=(RelativeLayout)findViewById(R.id.navigation_bar);
		logoImageViewLeft = (ImageView) findViewById(R.id.logo_iv_left);
		navigationButtonLeft = (Button) findViewById(R.id.navigation_button_left);
		navigationTxtLeft = (TextView) findViewById(R.id.navigation_txt_left);
		navigationTitleText = (TextView) findViewById(R.id.navigation_title_text);
		specGroup = (LinearLayout) findViewById(R.id.specGroup);
		frameworkExistBtn = (Button) findViewById(R.id.framework_exist_btn);//退出按钮
		frameworkExistBtn.setOnClickListener(this);
		
		LPUtils.setTitleButtonWH(frameworkExistBtn);
		LPUtils.scaledTHeightRel(navigationBar);
		
		Button leftBtn = (Button) findViewById(R.id.navigation_button_left);//返回 按钮*没用到，visible="gone"
		leftBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				popFragment();
			}
		});
		//语音服务加载
		initVoiceServer();
		microphoneBtn.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				if(event.getAction()==MotionEvent.ACTION_DOWN)
				{
					microphoneBtn.setBackgroundResource(R.drawable.mic_down);
					if(isNetworkAvailable()){
						vc.stopPlayer();
						if(vc.isStartAcquisition()){
							vc.stopAcquisition();
						}else{
							vc.startAcquisition();
							mic.setVisibility(View.VISIBLE);
						}
					}
				}else if(event.getAction()==MotionEvent.ACTION_UP)
				{
					microphoneBtn.setBackgroundResource(R.drawable.mic_up);
					vc.stopPlayer();
					vc.stopAcquisition();
					mic.setVisibility(View.GONE);
				}
				return false;
			}
		});
	}
	
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		Bundle inBundle = new Bundle();
		switch (v.getId()) {
		case R.id.microphoneBtn:     //麦克按钮
			if(System.currentTimeMillis() - last_onclik_date > 1000){
				if(isNetworkAvailable()){
					vc.stopPlayer();
					if(vc.isStartAcquisition()){
						vc.stopAcquisition();
					}else{
						vc.startAcquisition();
					}
				}
			}
			last_onclik_date = System.currentTimeMillis();
			break;
		case R.id.framework_exist_btn:  //退出
			exitApp();
			break;
		default:
			break;
		}
	}
	
	@Override
	public void finish() {
		// TODO Auto-generated method stub
		super.finish();
		vc.stopPlayer();
		vc.uninit();
	}

	/**
	 * 设置标题文本
	 * 
	 * @param title
	 */
	private void setTitle() {
		if (titleStack.size() != 0) {
			TextView titleView = (TextView) findViewById(R.id.navigation_title_text);
			String title = titleStack.peek();
			if ("".equals(title.trim())) {
				titleView.setVisibility(View.GONE);
			} else {
				titleView.setVisibility(View.VISIBLE);
			}
			if (title.length() > TITLE_LENGTH) {
				title = title.substring(0, TITLE_LENGTH) + "...";
			}
			titleView.setText(title);
		}

	}



	/**
	 * 压入碎片
	 * @param title
	 * @param fragment
	 */
	public Fragment pushFragment(String title, Fragment fragment) {
		try {
			Fragment currentfragment = null;
			if(fragmentStack.size() > 0 &&  (currentfragment = fragmentStack.peek()) != null){  //peek()只是查看堆栈的顶部对象，并不移除它
				if((fragment instanceof TalkFragment) && (currentfragment instanceof TalkFragment)){
					fragment = currentfragment;
					return fragment;
				}
			}
			fragmentStack.add(fragment);
			titleStack.push(title);
			setTitle();
			leftBtnVisible();
			exitBtnVisible();
			FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
			//R.id.navigation_container是个container，去除container中的fragment,用此处fragment替换
			ft.replace(R.id.navigation_container, fragment);
			if (fragmentStack.size() > 1) {
				//保存事务到BackStack中
				ft.addToBackStack("XIAOI");
			}
			ft.commit();
		} catch (Exception e) {
			// TODO: handle exception
			Utils.LogD(TAG, "压入碎片发生异常 title="+title+",fragmentType="+fragment.getClass().getName());
		}
		
		return fragment;
	}
	
	/**
	 * 弹出
	 */
	public void popFragment() {
		try {
			hideSoftInput();
			getSupportFragmentManager().popBackStackImmediate();//返回与this Activity交互的FragmentManager;pop the top of the stack,if there was one poped,return true else return false ;
			Fragment fragment = fragmentStack.pop();
			getSupportFragmentManager().beginTransaction().remove(fragment).commit();//beginTransaction():Start a series of edit operations on the Fragments associated with this FragmentManager.
			titleStack.pop();
			setTitle();
			leftBtnVisible();
			Utils.LogD(TAG,"弹出fragment=" + fragment + " size=" + fragmentStack.size());
		} catch (Exception e) {
			// TODO: handle exception
			Utils.LogD(TAG+"弹出fragment发送异常",e.toString());
		}
	}
	
	/**
	 * 获取语音对话Fragment
	 * @param tb
	 */
	public void addTalkFragmentData(TalkBean tb){
		TalkFragment talkFragment = null;
		if(fragmentStack.peek() instanceof TalkFragment){
			talkFragment =  (TalkFragment) fragmentStack.peek();
			talkFragment.addCurrTalkText(tb);
		}else{
			int size  = fragmentStack.size();
			for (int i = size; i > 0; i--) {
				Utils.LogD(TAG, "弹出fragmentStack...");
				Fragment fragment = fragmentStack.peek();
				if(fragment instanceof TalkFragment){
					talkFragment =  (TalkFragment) fragment;
					talkFragment.addTalkText(tb);
				}else{
					popFragment();
				}
			}
		}
	}
	
	/**
	 * 左上角返回按钮显示,if为TRUE显示logo图片
	 */
	private void leftBtnVisible() {
		try {
			Utils.LogD("mytag", "开始处理左上角按钮");
			Fragment fragment = fragmentStack.peek();
			if(fragment instanceof TalkFragment){
//				logoImageViewLeft.setVisibility(ImageView.VISIBLE);
				navigationButtonLeft.setVisibility(View.GONE);
			}else{
				navigationButtonLeft.setVisibility(View.VISIBLE);
				logoImageViewLeft.setVisibility(ImageView.GONE);
				navigationButtonLeft.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						popFragment();
					}
				});
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			Utils.LogD("mytag","fragmentStack.peek()出错");
		}
	}
	
	/**
	 * 退出按钮显示【返回就是退出按钮，没有返回按钮】
	 */
	private void exitBtnVisible(){
		try {
			Utils.LogD(TAG, "开始处理右上角退出按钮");
			Fragment fragment = fragmentStack.peek();
			if(fragment instanceof TalkFragment){
				frameworkExistBtn.setText("返回");
				frameworkExistBtn.setVisibility(View.VISIBLE);
				navigationButtonLeft.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						exitApp();
					}
				});
			}else{
				frameworkExistBtn.setVisibility(View.GONE);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			Utils.LogD(TAG, "fragmentStack.peek()出错");
		}
	}
	
	/**
	 * 初始化语音服务
	 */
	public void initVoiceServer(){
		vc = VoiceControl.getInstance();
		vc.init(VOICE_ASK_AREA, VOICE_SERVER_IP, VOICE_SERVER_PORT);
		vc.setVoiceControlListener(vcl,handler);
		volumeImages = new Drawable[]{
				getResources().getDrawable(R.drawable.mic1),
				getResources().getDrawable(R.drawable.mic2),
				getResources().getDrawable(R.drawable.mic3),
				getResources().getDrawable(R.drawable.mic4),
				getResources().getDrawable(R.drawable.mic5)};
	}

	
	private VoiceControlListener vcl = new VoiceControlListener() {
		@Override
		public void onVoiceControlState(final VoiceBundle vb) {
			// TODO Auto-generated method stub
			AnimationDrawable animation_recorder_states = null;
			switch (vb.getControlState()) {
			case WAIT_ACQUISITION:
				Utils.LogD(TAG, "等待语音采集");
				break;
			case START_ACQUISITION:
				Utils.LogD(TAG, "启动语音采集");
				break;
			case STOP_ACQUISITION:
				Utils.LogD(TAG, "停止语音采集");
				break;
			case BEGIN_ASR:
				Utils.LogD(TAG, "启动语音识别");
				break;
			case RUN_ASR:
				/**语音采集中，反馈的数据*/
				if(vb.getData().get(VoiceBundle.F_ASR_VOLUME) != null){
					int volume = Integer.parseInt(vb.getData().get(VoiceBundle.F_ASR_VOLUME).toString());
					mic.setBackgroundDrawable(volumeImages[(volume*5/100)>=volumeImages.length?volumeImages.length-1:volume*5/100]);
				}
				break;
			case END_ASR:
				Utils.LogD(TAG, "结束语音识别");
				addTalkFragmentData(new TalkBean<String>(TalkBean.SAY_ME, vb.getData().get(VoiceBundle.F_ASR_WORD).toString()));
				vc.askData(vb.getData().get(VoiceBundle.F_ASR_WORD).toString());
				break;
			case BEGIN_ASK:
				Utils.LogD(TAG,"小I智能回答启动");
				break;
			case END_ASK:
				Utils.LogD(TAG,"小I智能回答返回结果");
				if(vb.getAskDataInfo().isSuccess()){
					Plugin plugin = vb.getAskDataInfo().getAnswer().getPlugin();
					if(plugin != null && "weather".equals(plugin.getName())){
					}else{
						addTalkFragmentData(new TalkBean<Response>(TalkBean.SAY_HE, vb.getAskDataInfo().getAnswer()));
					}
					vc.startPlayer(vb.getAskDataInfo().getAnswer().getContent(),new PlayerCallBack() {
						@Override
						public void playerFinish(long playerDate) {
//							// TODO Auto-generated method stub
							cf.pushServerData(VoiceFrameActivity.this,vb.getAskDataInfo().getAnswer());
//							pushFragment("日历测试", new CalendarFrament(null, vc));
						}
					});
				}else{
					Toast.makeText(getApplicationContext(), "采集错误", Toast.LENGTH_SHORT).show();
				}
				break;
			case ERROR:
				Utils.LogD(TAG, "产生了一个errorCode="+vb.getData().get(VoiceBundle.F_ERROR_CODE)+",errorMsg="+vb.getData().get(VoiceBundle.F_ERROR_MSG)+"");
				vc.startPlayer(vb.getData().get(VoiceBundle.F_ERROR_MSG).toString());
				break;
			default:
				break;
			}
		}
	};
	private String errorStr;
	private String errorType;
	private String errorCode;
	private String errorConfirm;
	private String errorRelogin;
	private String errorCancel;
	protected ClientHello hello;
	
	/**
	 * 显示文本或者语音合成
	 * @param word
	 * @param isPlayer
	 */
	public void disWordOrPlayer(String word,boolean isDisplay,boolean isPlayer){
		if(word != null && word.length() > 0){
			Response response = new Response();
			response.setContent(word);
			if(isDisplay){
				addTalkFragmentData(new TalkBean<Response>(TalkBean.SAY_HE,response));
			}
			if(isPlayer){
				vc.startPlayer(word);
			}
		}
	}
	
	// 隐藏软软键盘
	private void hideSoftInput() {
		InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(navigationButtonLeft.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		int count = this.getSupportFragmentManager().getBackStackEntryCount();
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			if (count < 1 || fragmentStack.peek() instanceof TalkFragment){
				exitApp();
			}else{
				boolean isProcess = super.onKeyDown(keyCode, event);
				if (isProcess) {
					popFragment();
				}
				return isProcess;
			}
			return false;
		}else{
			return super.onKeyDown(keyCode, event);
		}
	}
	
	public void exitApp(){
		VcSession.getInstance().onCreateSession();
		VoiceFrameActivity.this.finish();

	}
	//判断网络连接是否正常，连外网
	private boolean isNetworkAvailable() {
		
        try {
            ConnectivityManager cm = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo info = cm.getActiveNetworkInfo();
            if(info != null && info.isConnected()){
            	return true;
            }else{
            	Dialog dialog = new AlertDialog.Builder(this)
        		.setTitle(R.string.common_prompt)
        		.setMessage(R.string.voie_frame_no_network)
        		.setNegativeButton(R.string.voie_frame_confirm,
        				new DialogInterface.OnClickListener() {
        					@Override
        					public void onClick(DialogInterface dialog,int which) {
        						dialog.dismiss();
        					}
        				}).create();
        		dialog.show();
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }
	
	@Override
	protected void onSaveInstanceState(Bundle outState) {
	        // super.onSaveInstanceState(outState);
	} 
	
	/** 集中处理异常
	 * <error string="" errorcode=""/>
	 * <error type="timeout" string="错误信息" relogin="重新登录" cancel="退出"/>
	 * **/
	public void handleException(String errMsg) {
		if (null != errMsg && errMsg.indexOf("<error") != -1) {
			String error = Utils.getXMLResponseAttribute(errMsg, "string=\"", 0, Utils.MATCH);
			// 错误信息
//			errorStr = errorStr != null || !errorStr.equals("") ? "错误信息:"+error +"\n" : "";
			errorStr = "错误信息:"+error;
			// 错误类型
			errorType = Utils.getXMLResponseAttribute(errMsg, "type=\"", 0, Utils.MATCH);
			// errorContent = Utils.getXMLResponseAttribute(errMsg, "content=\"", 0, Utils.MATCH);
			errorCode =Utils.getXMLResponseAttribute(errMsg, "errorcode=\"", 0, Utils.MATCH);
			
			// 错误信息弹出后按钮文本
			errorConfirm = Utils.getXMLResponseAttribute(errMsg, " confirm=\"", 0, Utils.MATCH);
			errorRelogin = Utils.getXMLResponseAttribute(errMsg, "relogin=\"", 0, Utils.MATCH);
			errorCancel = Utils.getXMLResponseAttribute(errMsg, "cancel=\"", 0, Utils.MATCH);
            
			errorConfirm = errorConfirm != null ? errorConfirm : getString(R.string.quit);
			errorRelogin = errorRelogin != null ? errorRelogin : getString(R.string.relogin);
			errorCancel = errorCancel != null ? errorCancel : getString(R.string.cancel);
			errorCode = errorCode != null ? "错误码:"+errorCode +"\n" : "";
			if(!errorCode.equals("")){
				errorStr=errorCode+errorStr;	
			}else{
				errorStr=error;
			}
			
			if (errorType != null) {
				if (errorType.equals("timeout")) {
					showErrorDailog("timeout");
				}
			}else{
				showErrorDailog("normal");
			}
		} else if (null != errMsg && !"".equals(errMsg)) {
			
			if (errMsg.contains(".NullPoi")) {
				errorStr=Utils.getConfigStringFormAsset(Utils
						.getActivity(), "httpError");
			}else{
				errorStr = errMsg;	
			}
			showErrorDailog("normal");

		} else {
			// responseCode
		}
	}

	// 弹出错误提示框
	public void showErrorDailog(String type) {
		final Builder ad = new AlertDialog.Builder(this);
		ad.setTitle(getString(R.string.alert)).setMessage(errorStr);
		if (type.equals("normal")) {
			ad.setPositiveButton(R.string.quit,
					new android.content.DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// BaseViewCopy.this.finish();
							// android.os.Process.killProcess(android.os.Process.myPid());
							// dialog.cancel();
						}
					}
			);
		} else if (type.equals("timeout")) {
			ad.setCancelable(false);
			ad.setPositiveButton(R.string.exit, new android.content.DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface arg0, int arg1) {
					exitSystem();
				}
			})
			.setNegativeButton(R.string.relogin,
					new android.content.DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					reConnect(VoiceFrameActivity.this);
					dialog.cancel();
				}
			}
			);
		}
		
		if(null != ad){
			this.runOnUiThread(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					ad.show();
				}
			});
		}
	}

	/**
	 * 重建加密通道
	 * @param baseViewCopy
	 */
	protected void reConnect(final VoiceFrameActivity baseViewCopy) {
		LPToastUtil.isBuildChannel = false;
		LPMid.getInstance().isTimeOut=true;
		
		LPMid.getInstance().waitDialog_.addFgTask(baseViewCopy, null, 0, 0, 0, new WaitDialog.Task(0) {
			String reply = null;
			@Override
			public void run(WaitDialog dlg) throws Exception {
				if(!Utils.isConnectByNet()){
					throw new Exception("网络未连接，请检查您的网络设置。");
				}
				hello = new ClientHello(VoiceFrameActivity.this, ConfigManager.SERVER_URI, LPMid.getInstance().midletVersion_, ConfigManager.CLIENT_HELLO,
						ConfigManager.CLIENT_KEY_EXCHANGE, ConfigManager.CLIENT_FACILITY_HELLO, Utils.CERTIFICATE, "");
				reply = ClientHello.getText();
			}

			public void onSuccess(WaitDialog dlg) {
				if (null != reply && !"".equalsIgnoreCase(reply)) {
					if(null != LPMid.getInstance().um_.data){
						LPMid.getInstance().um_.data.resetLoginInfo();
					}
					Message msg = new Message();
					hanlder.sendMessage(msg);
				}
				super.onSuccess(dlg);
			}
			public void onFailure(WaitDialog dlg) {
				handleException(getErrMsg());
			}
		});
	}

	private Handler hanlder = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			BankcommApplication.getInstance().exit();
			Intent intent = new Intent();
			intent.setClass(VoiceFrameActivity.this, BOCMainHome.class);				
			VoiceFrameActivity.this.startActivity(intent);
		}
	};
	
	/**
	 * 退出程序
	 */
	public void exitSystem() {
		/**
		 * 当退出时，要结束List中的所有activity add by chengli
		 * */
		BankcommApplication.getInstance().exit();
		// 停止程序开启的服务，保证程序退出后不会常驻内存
		Intent intent = new Intent();
		intent.setAction(getClass().getPackage().getName());
		stopService(intent);
		/**
		 * 一般是采用finish方法,但是在转换wifi和wap连接的时候会出现系统提示连接长时间死亡的情况.
		 */
		System.exit(0);
	}

}
